package com.xhtt.modules.task.service.impl;


import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xhtt.common.exception.RRException;
import com.xhtt.common.utils.CopyUtils;
import com.xhtt.common.utils.PageUtils;
import com.xhtt.common.utils.Query;
import com.xhtt.modules.cfg.entity.*;
import com.xhtt.modules.cfg.service.*;
import com.xhtt.modules.msg.entity.MsgInfo;
import com.xhtt.modules.msg.service.MsgInfoService;
import com.xhtt.modules.msg.service.MsgUserService;
import com.xhtt.modules.sys.entity.SysDeptEntity;
import com.xhtt.modules.sys.entity.SysUserEntity;
import com.xhtt.modules.sys.service.SysDeptService;
import com.xhtt.modules.sys.service.SysUserService;
import com.xhtt.modules.task.dao.TaskOperTaskMapper;
import com.xhtt.modules.task.entity.*;
import com.xhtt.modules.task.model.TaskOperModel;
import com.xhtt.modules.task.model.lmtask.TaskOperLMModel;
import com.xhtt.modules.task.model.msg.PlanTaskModel;
import com.xhtt.modules.task.model.oper.*;
import com.xhtt.modules.task.model.ship.WorkUserModel;
import com.xhtt.modules.task.service.TaskOperPlanService;
import com.xhtt.modules.task.service.TaskOperSeoLogService;
import com.xhtt.modules.task.service.TaskOperSeoService;
import com.xhtt.modules.task.service.TaskOperTaskService;
import com.xhtt.modules.task.utils.StaticUtils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.MDC;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionTemplate;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 操作分支任务-任务分配计划 服务实现类
 * </p>
 *
 * @author feipc
 * @since 2019-03-09
 */
@Service
public class TaskOperTaskServiceImpl extends ServiceImpl<TaskOperTaskMapper, TaskOperTask> implements TaskOperTaskService {
    @Autowired
    private TaskOperPlanService taskOperPlanService;
    @Autowired
    private SysUserService sysUserService;
    @Autowired
    private SysDeptService sysDeptService;
    @Autowired
    private CfgHoseInfoService cfgHoseInfoService;
    @Autowired
    private CfgTubeInfoService cfgTubeInfoService;
    @Autowired
    private CfgPumpInfoService cfgPumpInfoService;
    @Resource
    private TransactionTemplate transactionTemplate;
    @Resource
    private ThreadPoolTaskExecutor taskExecutor;
    @Autowired
    private MsgInfoService msgInfoService;
    @Autowired
    private MsgUserService msgUserService;
    @Autowired
    private CfgHoseProductService hoseProductService;
    @Autowired
    private CfgHoseLogService hoseLogService;
    @Autowired
    private CfgTubeProductService tubeProductService;
    @Autowired
    private CfgTubeLogService tubeLogService;
    @Autowired
    private CfgPumpProductService pumpProductService;
    @Autowired
    private CfgPumpLogService pumpLogService;
    @Autowired
    private TaskOperSeoService operSeoService;
    @Autowired
    private CfgWarnTaskService warnTaskService;
    @Autowired
    private TaskOperSeoService taskOperSeoService;
    @Autowired
    private TaskOperSeoLogService taskOperSeoLogService;

    @Override
    public ArrangeModel getTaskDetail(Integer planId, SysUserEntity user) {
        ArrangeModel sm = new ArrangeModel();
        TaskOperPlan operPlan = taskOperPlanService.getById(planId);
        if (null == operPlan) {
            throw new RRException("对象不存在");
        }
        sm.setPlanId(planId);
        sm.setMainTaskName(operPlan.getTaskName());
        List<TaskOperTask> taskList = this.list(new LambdaQueryWrapper<TaskOperTask>().eq(TaskOperTask::getOperPlanId, planId));

        if (operPlan.getStatus().intValue() == 2)//如果在待分配状态下，就只能看自己组的任务数据
        {
            //过滤下任务列表
            taskList.removeIf(t -> (null == t.getExecTeamId() || t.getExecTeamId().intValue() != user.getTeamId().intValue()));
        }
        for (TaskOperTask task : taskList) {
            if (null == task.getIfPhoto()) {
                task.setIfPhoto(0);//默认设置0
            }
            if (null == task.getIfConfirm()) {
                task.setIfConfirm(0);//默认设置0
            }
            if (null != task.getUserMainId()) {
                SysUserEntity u = sysUserService.getOne(new LambdaQueryWrapper<SysUserEntity>().eq(SysUserEntity::getUserId, task.getUserMainId()).select(SysUserEntity::getUserId, SysUserEntity::getName));
                task.setUserMainName(u.getName());
            }
            if (null != task.getExecTeamId()) {
                SysDeptEntity dept = sysDeptService.getOne(new LambdaQueryWrapper<SysDeptEntity>().eq(SysDeptEntity::getDeptId, task.getExecTeamId()));
                task.setExecTeamName(dept.getName());
            }
            if (null != task.getConfirmUser()) {
                SysUserEntity u = sysUserService.getOne(new LambdaQueryWrapper<SysUserEntity>().eq(SysUserEntity::getUserId, task.getConfirmUser()).select(SysUserEntity::getUserId, SysUserEntity::getName));
                task.setConfirmUserName(u.getName());
            }
        }
        sm.setTasks(taskList);
        return sm;
    }

    @Override
    @Transactional
    public void pubTask(List<TaskOperTask> tasks, SysUserEntity user) {
        List<TaskOperTask> dbs = new ArrayList<>();
        TaskOperTask db;
        Integer planId = 0;
        List<Integer> thisIds = new ArrayList<>();//
        for (TaskOperTask taskOperTask : tasks) {
            thisIds.add(taskOperTask.getId());
            if (CollectionUtils.isNotEmpty(taskOperTask.getUserAssistModel())) {
                taskOperTask.setUserAssist(JSON.toJSONString(taskOperTask.getUserAssistModel()));
            } else {
                taskOperTask.setUserAssist(JSON.toJSONString(Collections.EMPTY_LIST));
            }
            db = this.getById(taskOperTask.getId());
            CopyUtils.copyProperties(taskOperTask, db);
            db.setStatus(4);
            db.setPubTime(LocalDateTime.now());
            //判断下是不是有确认人，因为除了管线任务会手动设置 其他任务要默认选某组的组长（选了需要确认的话）谁发布 谁确认，一般都是组长发布
//            if (null == db.getConfirmUser() && db.getIfConfirm().intValue() == 1) {//就算不需要确认 也保存下确认人，证明下是这个人发布的，后面管线清洗任务记日志要用
            db.setConfirmUser(user.getUserId().intValue());
            db.setConfirmUserName(user.getName());
//            }
            dbs.add(db);
            planId = taskOperTask.getOperPlanId();
        }
        this.updateBatchById(dbs);
        //更新主任务状态为4
        //如果这个主任务的所有子任务都被分配完了 那就更新主任务状态为4
        int count = this.count(new LambdaQueryWrapper<TaskOperTask>().eq(TaskOperTask::getOperPlanId, planId).
                eq(TaskOperTask::getStatus, 0)
                .notIn(TaskOperTask::getId, thisIds));
        if (count == 0) {
            TaskOperPlan plan = new TaskOperPlan();
            plan.setId(planId);
            plan.setStatus(4);
            taskOperPlanService.updateById(plan);
        }

        //发消息
        taskExecutor.submit(() -> {
            List<MsgInfo> msgList = new ArrayList<>();
            for (TaskOperTask operTask : dbs) {
                PlanTaskModel ptm = new PlanTaskModel(operTask.getId(), operTask.getMainTaskName(), operTask.getName(), "", operTask.getTaskStartDate(), operTask.getUserAssistModel());

                Set<Integer> userIds = new HashSet<>();
                MsgInfo msg = new MsgInfo("计划任务", "操作任务:" + operTask.getMainTaskName(), "任务待完成提交", JSON.toJSONString(ptm));
                userIds.add(operTask.getUserMainId());
                msg.setUserIdList(userIds);
                msgList.add(msg);
            }
            msgInfoService.saveMsgBatch(msgList);
        });
    }

    @Override
    public PageUtils confirmTaskList(Map<String, Object> params) {
        Page<TaskOperTask> page = new Query<TaskOperTask>(params).getPage();
        page.setRecords(baseMapper.confirmTaskList(page, params));
        return new PageUtils(page);
    }

    @Override
    public TaskOperModel taskOperDetail(Integer taskId) {
        TaskOperTask task = this.getById(taskId);
        if (null == task) {
            throw new RRException("无数据");
        }
//        TaskOperPlan plan = taskOperPlanService.getById(task.getOperPlanId());
        String operDetail = task.getOperDetail();
        if (StringUtils.isEmpty(operDetail)) {
            if (task.getType().intValue() == 14)//14滤芯更换
            {
                TaskOperLXGHModel model = new TaskOperLXGHModel();
                model.setTaskId(taskId);
                return model;
            } else if (task.getType().intValue() == 18)//18打尺、取样
            {
                TaskOperDCQYModel model = new TaskOperDCQYModel();
                TaskOperPlan plan = taskOperPlanService.getOne(new LambdaQueryWrapper<TaskOperPlan>().eq(TaskOperPlan::getId, task.getOperPlanId()).select(TaskOperPlan::getId, TaskOperPlan::getProductName, TaskOperPlan::getPotName));
                model.setProductName(plan.getProductName());
                model.setPotName(plan.getPotName());
                model.setTaskId(taskId);
                return model;
            } else if (task.getType().intValue() == 19)//VOCEC
            {
                TaskOperVOCECModel model = new TaskOperVOCECModel();
                model.setTaskId(taskId);
                return model;
            } else if (task.getType().intValue() == 20)//20 CCR
            {
                TaskOperCCRModel model = new TaskOperCCRModel();
                model.setTaskId(taskId);
                return model;
            } else if (task.getType().intValue() == 21)//21 管线清洗
            {
                TaskOperOtherModel model = new TaskOperOtherModel();
                model.setTaskId(taskId);
                TaskOperPlan plan = taskOperPlanService.getOne(new LambdaQueryWrapper<TaskOperPlan>().eq(TaskOperPlan::getId, task.getOperPlanId()).select(TaskOperPlan::getId, TaskOperPlan::getLine));
                if (null != plan && StringUtils.isNotEmpty(plan.getLine())) {
                    LineModel lineModel = JSON.parseObject(plan.getLine(), LineModel.class);
//                    List<String> number = new ArrayList<>();
                    List<CfgHoseInfo> hoseList = lineModel.getHoseList();
                    List<CfgTubeInfo> tubeList = lineModel.getTubeList();
                    List<CfgPumpInfo> pumpList = lineModel.getPumpList();
                    if (CollectionUtils.isNotEmpty(hoseList)) {
                        model.setHoseNumbers(StringUtils.join(hoseList.stream().map(h -> h.getNumberNo()).collect(Collectors.toList()), ","));
                    }
                    if (CollectionUtils.isNotEmpty(tubeList)) {
                        model.setTubeNumbers(StringUtils.join(tubeList.stream().map(t -> t.getNumberNo()).collect(Collectors.toList()), ","));
                    }
                    if (CollectionUtils.isNotEmpty(pumpList)) {
                        model.setPumpNumbers(StringUtils.join(pumpList.stream().map(p -> p.getNumberNo()).collect(Collectors.toList()), ","));
                    }
//                    model.setGxh(StringUtils.join(number, ","));
                }
                return model;
            } else if (task.getType().intValue() == 101)//101 LM
            {
                TaskOperLMModel model = new TaskOperLMModel();
                model.setTaskId(taskId);
                return model;
            } else {
                TaskOperOtherModel model = new TaskOperOtherModel();
                model.setTaskId(taskId);
                return model;
            }

        } else {
            if (task.getType().intValue() == 14)//14滤芯更换
            {
                TaskOperLXGHModel model = JSON.parseObject(operDetail, TaskOperLXGHModel.class);
                model.setConfirmResult(task.getConfirmStatus());
                model.setConfirmReason(task.getConfirmReason());
                return model;
            } else if (task.getType().intValue() == 18)//18打尺、取样
            {
                TaskOperDCQYModel model = JSON.parseObject(operDetail, TaskOperDCQYModel.class);
                model.setConfirmResult(task.getConfirmStatus());
                model.setConfirmReason(task.getConfirmReason());
                return model;
            } else if (task.getType().intValue() == 19)//18VOCEC
            {
                TaskOperVOCECModel model = JSON.parseObject(operDetail, TaskOperVOCECModel.class);
                model.setConfirmResult(task.getConfirmStatus());
                model.setConfirmReason(task.getConfirmReason());
                return model;
            } else if (task.getType().intValue() == 20)//20 CCR
            {
                //这个接口app调用 获取ccr任务详情，只获取当前操作的这次ccr记录
                List<TaskOperCCRModel> ccrModelList = JSON.parseArray(operDetail, TaskOperCCRModel.class);
                ccrModelList.forEach(taskOperCCRModel -> {
                    taskOperCCRModel.setConfirmReason(task.getConfirmReason());
                    taskOperCCRModel.setConfirmResult(task.getConfirmStatus());
                });
                int done = task.getCcrDone();
                int nowTime = done + 1;//本次操作次数
                if (ccrModelList.size() == nowTime)//说明之前临时保存过了，就直接取
                {
                    return ccrModelList.get(nowTime - 1);
                } else {
                    com.xhtt.modules.task.model.oper.TaskOperCCRModel model = new TaskOperCCRModel();
                    model.setTaskId(taskId);
                    return model;
                }
            } else if (task.getType().intValue() == 101)//101 LM
            {
                TaskOperLMModel model = JSON.parseObject(operDetail, TaskOperLMModel.class);
                model.setConfirmResult(task.getConfirmStatus());
                model.setConfirmReason(task.getConfirmReason());
                return model;
            } else {
                TaskOperOtherModel model = JSON.parseObject(operDetail, TaskOperOtherModel.class);
                model.setConfirmResult(task.getConfirmStatus());
                model.setConfirmReason(task.getConfirmReason());
                return model;
            }

        }

    }

    @Override
    public void tempSave(TaskOperModel model) {
        TaskOperTask task = this.getById(model.getTaskId());
        if (null == task) {
            throw new RRException("对象不存在");
        }
        checkTask(task, model);
//        task.setPubTime(LocalDateTime.now());为什么会设置分配时间呢？？？我也不知道了，但是说不通啊，所以就注释了
        this.updateById(task);
    }

    @Override
    public void submitTask(TaskOperModel model) {
        TaskOperTask tt = transactionTemplate.execute(ts -> {
            try {
                TaskOperTask task = this.getById(model.getTaskId());
                if (null == task) {
                    throw new RRException("对象不存在");
                }
                boolean skipConfirm = null == model.getSkipConfirm() ? false : model.getSkipConfirm();//是否直接不用干活直接提交
                if (!skipConfirm) {
                    checkTask(task, model);
                    //ccr任务要判断操的次数
                    if (task.getType().intValue() == 20)//CCR
                    {
                        //设置本次的完成时间-取出最后一条更新一下时间就好了
                        List<TaskOperCCRModel> ccrList = JSON.parseArray(task.getOperDetail(), TaskOperCCRModel.class);
                        int size = ccrList.size();
                        TaskOperCCRModel lastCCR = ccrList.get(size - 1);
                        lastCCR.setFinishTime(LocalDateTime.now());
                        task.setOperDetail(JSON.toJSONString(ccrList));

                        int total = task.getCcrTotal();
                        int done = task.getCcrDone() + 1;
                        task.setCcrDone(done);
                        if (total != done)//说明这次ccr没全做完
                        {
                            this.updateById(task);
                            return null;
                        }
                    }
                }

                task.setFinishTime(LocalDateTime.now());//完成时间设置
                task.setStatus(9);//状态设置
                //判断是否要确认，不要的话直接把确认状态改成1了，状态改成10 已确认
                if (task.getIfConfirm() == 0) {
                    task.setConfirmStatus(1);
                    task.setStatus(10);
                }
                this.updateById(task);

                //判断是否所有子任务都做完了，是的话就更新主任务的状态为9
                int count = this.count(new LambdaQueryWrapper<TaskOperTask>().eq(TaskOperTask::getOperPlanId, task.getOperPlanId()).ne(TaskOperTask::getId, task.getId()).lt(TaskOperTask::getStatus, 9));
                if (count == 0) {
                    TaskOperPlan p = new TaskOperPlan();
                    p.setStatus(9);
                    p.setId(task.getOperPlanId());
                    //如果自己是不用确认的，那就判断是否所有子任务都确认完了，是的话就更新主任务的状态为10
                    if (task.getIfConfirm() == 0) {
                        int countC = this.count(new LambdaQueryWrapper<TaskOperTask>().eq(TaskOperTask::getOperPlanId, task.getOperPlanId()).ne(TaskOperTask::getId, task.getId()).lt(TaskOperTask::getStatus, 10));
                        if (countC == 0) {
                            p.setStatus(10);
                        }
                    }

                    taskOperPlanService.updateById(p);
                }
                return task;
            } catch (Exception e) {
                ts.setRollbackOnly();
                e.printStackTrace();
                return null;
            }
        });
        if (null != tt && tt.getStatus().intValue() == 10) {
            //完成就要同步数据到seo
            taskExecutor.submit(() -> {
                TaskOperSeo seo = taskOperPlanService.dataToSeo(tt.getId());
                operSeoService.save(seo);
            });
        }
        if (null != tt && tt.getIfConfirm().intValue() == 0) {
            //这里清空是因为有些任务不需要确认
            taskExecutor.submit(() -> flushProduct(tt));
        }
        //发消息
        taskExecutor.submit(() -> {
            if (null != tt && tt.getIfConfirm() == 1) {
                PlanTaskModel ptm = new PlanTaskModel(tt.getId(), tt.getMainTaskName(), tt.getName(), "", tt.getTaskStartDate(), tt.getUserAssistModel());

                TaskOperPlan plan = taskOperPlanService.getOne(new LambdaQueryWrapper<TaskOperPlan>().eq(TaskOperPlan::getId, tt.getOperPlanId()).select(TaskOperPlan::getId, TaskOperPlan::getTaskName));
                MsgInfo msg = new MsgInfo("计划任务", "操作任务:" + plan.getTaskName(), "任务待确认", JSON.toJSONString(ptm));

                List<Integer> userIds = new ArrayList<>();
                userIds.add(tt.getConfirmUser());
//                msg.setUserIdList(userIds);
                msgUserService.insertBatch(msg, userIds);
            }
        });

    }

    private void flushProduct(TaskOperTask task) {
        //判断这个是不是管线清洗任务
        TaskOperPlan plan = taskOperPlanService.getOne(new LambdaQueryWrapper<TaskOperPlan>().eq(TaskOperPlan::getId, task.getOperPlanId()));
        if (null != plan && (plan.getType().intValue() == 2 || task.getType().intValue() == 21))// 临时任务里面也有管线清洗21
        {
            //判断是否所有子任务都确认完了(不管是正常确认还是不正常确认)，是的话就他妈的把管道的当前产品都清空
            int count = this.count(new LambdaQueryWrapper<TaskOperTask>().eq(TaskOperTask::getOperPlanId, task.getOperPlanId()).isNull(TaskOperTask::getConfirmStatus));
            if (count == 0) {
                //获取这个任务的软管 硬管 泵
                LineModel lineModel = plan.getLineModel();
                if (null != lineModel) {
                    List<CfgHoseInfo> hoseList = lineModel.getHoseList();
                    List<CfgTubeInfo> tubeList = lineModel.getTubeList();
                    List<CfgPumpInfo> pumpList = lineModel.getPumpList();
                    Integer userId = task.getConfirmUser();
                    String deptUser = "";
                    if (null != userId) {
                        deptUser = sysUserService.getUserWithDept(userId);
                    }
                    if (CollectionUtils.isNotEmpty(hoseList)) {
                        List<Integer> hoseIds = hoseList.stream().map(cfgHoseInfo -> cfgHoseInfo.getId()).collect(Collectors.toList());
                        hoseLog(hoseIds, deptUser);
                        cfgHoseInfoService.flushProduct(hoseIds);
                    }
                    if (CollectionUtils.isNotEmpty(tubeList)) {
                        List<Integer> tubeIds = tubeList.stream().map(cfgTubeInfo -> cfgTubeInfo.getId()).collect(Collectors.toList());
                        tubeLog(tubeIds, deptUser);
                        cfgTubeInfoService.flushProduct(tubeIds);
                    }
                    if (CollectionUtils.isNotEmpty(pumpList)) {
                        List<Integer> pumpIds = pumpList.stream().map(cfgPumpInfo -> cfgPumpInfo.getId()).collect(Collectors.toList());
                        pumpLog(pumpIds, deptUser);
                        cfgPumpInfoService.flushProduct(pumpIds);
                    }

                }
            }
        }
    }

    private void hoseLog(List<Integer> hoseIds, String deptUser) {
        List<CfgHoseLog> logs = new ArrayList();
        CfgHoseLog log;
        for (Integer hoseId : hoseIds) {
            CfgHoseProduct oldComProduct = hoseProductService.getOne(new LambdaQueryWrapper<CfgHoseProduct>().eq(CfgHoseProduct::getHoseId, hoseId).eq(CfgHoseProduct::getType, 1));
            String comProductInfo = (null == oldComProduct.getName() ? "" : oldComProduct.getName()) + " → " + "";
            log = new CfgHoseLog();
            log.setHoseId(hoseId);
            log.setDeptUser(deptUser);
            log.setPressureLevelInfo("");
            log.setRfidInfo("");
            log.setDateScrapInfo("");
            log.setDateSuppressInfo("");
            log.setComProductInfo(comProductInfo);
            log.setSpareProductInfo("");
            logs.add(log);
        }
        hoseLogService.saveBatch(logs);
    }

    private void tubeLog(List<Integer> tubeIds, String deptUser) {
        List<CfgTubeLog> logs = new ArrayList();
        CfgTubeLog log;
        for (Integer tubeId : tubeIds) {
            CfgTubeProduct oldComProduct = tubeProductService.getOne(new LambdaQueryWrapper<CfgTubeProduct>().eq(CfgTubeProduct::getTubeId, tubeId).eq(CfgTubeProduct::getType, 1));
            String comProductInfo = (null == oldComProduct.getName() ? "" : oldComProduct.getName()) + " → " + "";
            log = new CfgTubeLog();
            log.setTubeId(tubeId);
            log.setDeptUser(deptUser);
            log.setRfidInfo("");
            log.setComProductInfo(comProductInfo);
            log.setSpareProductInfo("");
            logs.add(log);
        }
        tubeLogService.saveBatch(logs);
    }

    private void pumpLog(List<Integer> pumpIds, String deptUser) {
        List<CfgPumpLog> logs = new ArrayList();
        CfgPumpLog log;
        for (Integer pumpId : pumpIds) {
            CfgPumpProduct oldComProduct = pumpProductService.getOne(new LambdaQueryWrapper<CfgPumpProduct>().eq(CfgPumpProduct::getPumpId, pumpId).eq(CfgPumpProduct::getType, 1));
            String comProductInfo = (null == oldComProduct.getName() ? "" : oldComProduct.getName()) + " → " + "";
            log = new CfgPumpLog();
            log.setPumpId(pumpId);
            log.setDeptUser(deptUser);
            log.setRfidInfo("");
            log.setComProductInfo(comProductInfo);

            logs.add(log);
        }
        pumpLogService.saveBatch(logs);
    }

    @Override
    public void commitTask(TaskOperModel model) {
        TaskOperTask tt = transactionTemplate.execute(transactionStatus -> {
            try {
                TaskOperTask task = this.getById(model.getTaskId());
                task.setConfirmStatus(model.getConfirmResult());
                task.setConfirmReason(model.getConfirmReason());
                task.setStatus(10);//确认完成
                //判断是不是子任务都确认完了( 除了自己以外，没有状态小于9的数据了)，是的话把主任务状态也改一下
                Integer operPlanId = task.getOperPlanId();
                int count = this.count(new LambdaQueryWrapper<TaskOperTask>().eq(TaskOperTask::getOperPlanId, operPlanId).lt(TaskOperTask::getStatus, 10).ne(TaskOperTask::getId, task.getId()));
                if (0 == count) {
                    TaskOperPlan plan = new TaskOperPlan();
                    plan.setId(operPlanId);
                    plan.setStatus(10);
                    taskOperPlanService.updateById(plan);
                }
                this.updateById(task);
                return task;
            } catch (Throwable e) {
                transactionStatus.setRollbackOnly();
            }
            return null;
        });

        if (null != tt) {
            taskExecutor.submit(() -> flushProduct(tt));//管线清洗 清除管线产品
            //完成就要同步数据到seo
            taskExecutor.submit(() -> {
                TaskOperSeo seo = taskOperPlanService.dataToSeo(tt.getId());
                operSeoService.save(seo);
            });
        }
    }

    @Override
    @Transactional
    public void pubTempTask(TaskOperPlan operPlan) {
        TaskOperTask task = operPlan.getTaskOperTask();
        operPlan.setType(9);//1清罐2管线清洗3洗罐4通球 9 临时任务
        operPlan.setTaskName(StaticUtils.getTempTaskName(task.getType().intValue()));
        operPlan.setStatus(4);//直接进入现场作业阶段
        operPlan.setPlanStartDate(task.getTaskStartDate());
        if (task.getType().intValue() == 21)//临时任务-管线清洗
        {
            if (null == operPlan.getLineModel()) {
                throw new RRException("管线信息不能为空");
            }
            operPlan.setLine(JSON.toJSONString(operPlan.getLineModel()));
        }
        taskOperPlanService.save(operPlan);

        if (CollectionUtils.isNotEmpty(task.getUserAssistModel())) {
            task.setUserAssist(JSON.toJSONString(task.getUserAssistModel()));
        }
        task.setPubTime(LocalDateTime.now());
        task.setOperPlanId(operPlan.getId());
        task.setStatus(4);//直接进入现场作业阶段
        //type  11收料 12送料 13炭桶更换 14滤芯更换 15循环 16加热 17制冷 18打尺、取样 19VOCEC检测 20CCR记录 21管线清洗 99其他
        //判断下是不是有确认人，因为除了管线任务会手动设置 其他任务要默认选某组的组长（选了需要确认的话）
//        if (task.getIfConfirm().intValue() == 1) {就算不需要确认 也保存下确认人，证明下是这个人发布的，后面管线清洗任务记日志要用
        String str = MDC.get("user");
        if (StringUtils.isNotEmpty(str)) {
            SysUserEntity user = JSON.parseObject(str, SysUserEntity.class);
            task.setConfirmUser(user.getUserId().intValue());
            task.setConfirmUserName(user.getName());
        }
//        }
        //判断有没有任务频率,也就ccr任务会有了 fuck
        if (StringUtils.isNotEmpty(task.getTaskFre()) && task.getType().intValue() == 20) {
            int count = StaticUtils.gettaskCount(task.getTaskFre(), task.getTaskStartDate(), task.getTaskEndDate());
            task.setCcrTotal(count);
            task.setCcrDone(0);
        }

        this.save(task);
        //发消息
        taskExecutor.submit(() -> {
            PlanTaskModel ptm = new PlanTaskModel(task.getId(), operPlan.getTaskName(), task.getName(), "", task.getTaskStartDate(), task.getUserAssistModel());
            List<Integer> userIds = new ArrayList<>();
            MsgInfo msg = new MsgInfo("计划任务", "操作任务:" + operPlan.getTaskName(), "任务待完成提交", JSON.toJSONString(ptm));
            userIds.add(task.getUserMainId());
            msgUserService.insertBatch(msg, userIds);
        });
    }

    @Override
    public List<TaskOperTask> shiftsList(Integer selfId) {
        return baseMapper.shiftsList(selfId);
    }

    @Override
    public List<TaskOperCCRModel> taskCCRDetail(Integer taskId, int userId) {
        TaskOperTask task = this.getOne(new LambdaQueryWrapper<TaskOperTask>().eq(TaskOperTask::getId, taskId).select(TaskOperTask::getId, TaskOperTask::getConfirmUser,
                TaskOperTask::getOperDetail, TaskOperTask::getConfirmStatus, TaskOperTask::getConfirmReason));
        if (null == task) {
            throw new RRException("对象不存在");
        }
        String detail = task.getOperDetail();
        if (StringUtils.isEmpty(detail)) {
            return Collections.EMPTY_LIST;
        } else {
            List<TaskOperCCRModel> list = JSON.parseArray(detail, TaskOperCCRModel.class);
            list.forEach(taskOperCCRModel -> {
                        if (null != task.getConfirmUser()) {
                            taskOperCCRModel.setConfirmResult(task.getConfirmStatus());
                            taskOperCCRModel.setConfirmReason(task.getConfirmReason());
                        }
                    }
            );
            return list;
        }
    }

    @Override
    public String taskCCRStatus(Integer taskId) {
        TaskOperTask task = this.getOne(new LambdaQueryWrapper<TaskOperTask>().eq(TaskOperTask::getId, taskId).select(TaskOperTask::getCcrDone, TaskOperTask::getOperDetail));
        if (null == task) {
            throw new RRException("对象不存在");
        }
        int done = task.getCcrDone();
        String detail = task.getOperDetail();
        if (StringUtils.isEmpty(detail)) {
            return "未开始";
        }
        int nowTime = done + 1;//本次的次数
        List<TaskOperCCRModel> modelList = JSON.parseArray(detail, TaskOperCCRModel.class);
        if (modelList.size() < nowTime) {
            return "未开始";
        } else {
            return "进行中";
        }
    }

    @Override
    @Transactional
    public void start(Integer taskId) {
        TaskOperTask task = this.getOne(new LambdaQueryWrapper<TaskOperTask>().eq(TaskOperTask::getId, taskId).select(TaskOperTask::getId, TaskOperTask::getOperPlanId, TaskOperTask::getType, TaskOperTask::getOperDetail, TaskOperTask::getStartTime));
        if (null == task) {
            throw new RRException("对象不存在");
        }
//        if (task.getType().intValue() == 9)//如果是临时任务，那么就把计划开始时间设置成现在把
//        {
//            TaskOperPlan plan = taskOperPlanService.getOne(new LambdaQueryWrapper<TaskOperPlan>().eq(TaskOperPlan::getId, task.getOperPlanId()).select(TaskOperPlan::getId));
//            if (null != plan) {
//                plan.setPlanStartDate(LocalDateTime.now());
//                taskOperPlanService.updateById(plan);
//            }
//        }
        if (task.getType().intValue() == 20)//如果是ccr任务 他妈的还要特殊处理，真的是日了🐶了
        {
            TaskOperCCRModel ccr = new TaskOperCCRModel();
            ccr.setStartTime(LocalDateTime.now());
            String detail = task.getOperDetail();
            List<TaskOperCCRModel> ccrList;
            if (StringUtils.isNotEmpty(detail)) {
                ccrList = JSON.parseArray(detail, com.xhtt.modules.task.model.oper.TaskOperCCRModel.class);
                ccrList.add(ccr);
            } else {
                ccrList = new ArrayList<>();
                ccrList.add(ccr);
            }
            task.setOperDetail(JSON.toJSONString(ccrList));
        }
        task.setStartTime(LocalDateTime.now());
        this.updateById(task);
    }

    @Override
    public PageUtils seoList(Map<String, Object> params) {
        Page<TaskOperSeo> page = new Query<TaskOperSeo>(params).getPage();
        List<TaskOperSeo> list = baseMapper.seoList(page, params);
        for (TaskOperSeo seo : list) {
            if (seo.getStatus().intValue() != 10 && seo.getStatus().intValue() != 8) {
                StaticUtils.setLine(seo);
            }
        }
        List<CfgWarnTask> warnTaskList = warnTaskService.list();
        Map<String, Integer> warnStartMap = new HashMap<>();
        Map<String, Integer> warnFinishMap = new HashMap<>();
        for (CfgWarnTask wt : warnTaskList) {
            warnStartMap.put(wt.getPlan() + "-" + wt.getPlanType() + "-" + wt.getTaskType(), wt.getTime1());
            warnFinishMap.put(wt.getPlan() + "-" + wt.getPlanType() + "-" + wt.getTaskType(), wt.getTime2());
        }
        if (warnStartMap.size() != 0) {
            for (TaskOperSeo seo : list) {
                Integer time = warnStartMap.get("oper-" + seo.getPlanType() + "-" + seo.getTaskType());
                if (null == time || time.intValue() < 0) {
                    continue;
                }
                LocalDateTime planStartDate = seo.getPlanStartDate();
                LocalDateTime startTime = seo.getStartTime();
                if (null != planStartDate && null != startTime) {
                    LocalDateTime deadline = planStartDate.plusMinutes(time);
                    if (startTime.compareTo(deadline) > 0) {
                        seo.setStartTimeIfWarn(1);
                    }
                }
            }
        }
        if (warnFinishMap.size() != 0) {
            for (TaskOperSeo seo : list) {
                Integer time = warnFinishMap.get("oper-" + seo.getPlanType() + "-" + seo.getTaskType());
                if (null == time || time.intValue() < 0) {
                    continue;
                }
                LocalDateTime finishTime = seo.getFinishTime();
                LocalDateTime startTime = seo.getStartTime();
                if (null != finishTime && null != startTime) {
                    LocalDateTime deadline = startTime.plusMinutes(time);
                    if (finishTime.compareTo(deadline) > 0) {
                        seo.setFinishTimeIfWarn(1);
                    }
                }
            }
        }
        page.setRecords(list);
        return new PageUtils(page);
    }

    @Override
    @Transactional
    public void seoEdit(TaskOperSeo seo, SysUserEntity user) {
        taskOperSeoService.updateById(seo);
        TaskOperSeoLog seoLog = new TaskOperSeoLog();
        seoLog.setId(seo.getId());
        seoLog.setUserId(user.getUserId().intValue());
        seoLog.setUserName(user.getName());
        taskOperSeoLogService.save(seoLog);
    }

    private void checkTask(TaskOperTask task, TaskOperModel model) {
        //判断下类型吧
        int type = task.getType().intValue();
        if (14 == type) {
            TaskOperLXGHModel connectModel = new TaskOperLXGHModel();
            try {
                CopyUtils.copyProperties(model, connectModel);
            } catch (Exception e) {
                throw new RRException("类型与所传参数不匹配");
            }
            task.setOperDetail(JSON.toJSONString(connectModel));
        } else if (18 == type) {
            TaskOperDCQYModel lmModel = new TaskOperDCQYModel();
            try {
                CopyUtils.copyProperties(model, lmModel);
            } catch (Exception e) {
                throw new RRException("类型与所传参数不匹配");
            }
            task.setOperDetail(JSON.toJSONString(lmModel));
        } else if (19 == type) {
            TaskOperVOCECModel lmModel = new TaskOperVOCECModel();
            try {
                CopyUtils.copyProperties(model, lmModel);
            } catch (Exception e) {
                throw new RRException("类型与所传参数不匹配");
            }
            task.setOperDetail(JSON.toJSONString(lmModel));
        } else if (20 == type) {
            TaskOperCCRModel ccrModel = new TaskOperCCRModel();
            try {
                CopyUtils.copyProperties(model, ccrModel);
            } catch (Exception e) {
                throw new RRException("类型与所传参数不匹配");
            }
            //ccr任务跟狗屎一样恶心的需求处理
            String detail = task.getOperDetail();
            if (StringUtils.isEmpty(detail))//第一次添加
            {
                List<TaskOperCCRModel> list = new ArrayList<>();
                list.add(ccrModel);
                task.setOperDetail(JSON.toJSONString(list));
            } else {
                int done = task.getCcrDone();
                int nowTime = done + 1;//本次操作的次数
                List<com.xhtt.modules.task.model.oper.TaskOperCCRModel> list = JSON.parseArray(detail, com.xhtt.modules.task.model.oper.TaskOperCCRModel.class);
                if (list.size() == nowTime)//说明临时保存过
                {
                    //那就把这条更新一下把
                    list.set(nowTime - 1, ccrModel);
                } else//说明当前是第一次保存这次，有点绕口，反正就是这个意思
                {
                    //那就把这次的对象放进list
                    list.add(ccrModel);
                }
                task.setOperDetail(JSON.toJSONString(list));
            }
        } else if (101 == type) {//Lm任务
            TaskOperLMModel lmModel = new TaskOperLMModel();
            try {
                CopyUtils.copyProperties(model, lmModel);
            } catch (Exception e) {
                throw new RRException("类型与所传参数不匹配");
            }
            task.setOperDetail(JSON.toJSONString(lmModel));
        } else {
            TaskOperOtherModel otherModel = new TaskOperOtherModel();
            otherModel.setUserMain(sysUserService.getOne(new LambdaQueryWrapper<SysUserEntity>().eq(SysUserEntity::getUserId, task.getUserMainId())).getName());
            String userAssist = task.getUserAssist();
            if (StringUtils.isNotEmpty(userAssist)) {
                List<WorkUserModel> us = JSON.parseArray(userAssist, WorkUserModel.class);
                List<String> ss = us.stream().map(workUserModel -> workUserModel.getName()).collect(Collectors.toList());
                otherModel.setUserAssist(String.join(",", ss));
            }
            try {
                CopyUtils.copyProperties(model, otherModel);
            } catch (Exception e) {
                throw new RRException("类型与所传参数不匹配");
            }
            task.setOperDetail(JSON.toJSONString(otherModel));
        }
    }
}
